//========================================================== 
//  TaskControl.cpp
//  控制任务的执行
//==========================================================
#include <stdio.h>
#include "global.h"
#include "util.h"
#include "ImxErr.h"


using namespace std;
using namespace	Imx;

//======Data Manager========================================
DataManager::DataManager()
{
	int i,j;
	printf("======system max devID [%03d]\n",MAX_DEVS);
	printf("======system max chnNo [%03d]\n",MAX_CHN);
	_cachedDsr.resize(MAX_DEVS);
	for(i=0;i<MAX_DEVS;i++)
	{
		_cachedDsr[i].csr.resize(MAX_CHN);
	}
}

DataManager::~DataManager()
{
}

void
DataManager::initTestData()
{
	u8 i,j;
	for(i=0;i<MAX_DEVS;i++)
	{
		_cachedDsr[i].devState = IE_OK;
		for(j=0;j<MAX_CHN;j++)
		{
			_cachedDsr[i].csr[j].devId = i;
			_cachedDsr[i].csr[j].chnNo = j;
			_cachedDsr[i].csr[j].chnState = IE_OK;
		}
	}
}

ChnStateReport
DataManager::queryChnState(u8 devId, u8 chnNo)
{
	ChnStateReport csr;
	if(devId > 0)
	{
		if(chnNo > 0)// 大于零表示取指定通道
		{
			csr.resize(1);
			csr[0] = _cachedDsr[devId - 1].csr[chnNo - 1];
			return csr;
		}
		else if(chnNo == 0)	// 等于零表示取所有通道
		{
			return _cachedDsr[devId -1].csr;
		}
	}
	return csr;	// 错误返回空
}

DevStateReport
DataManager::queryDevState(u8 devId)
{
	DevStateReport dsr;
	if(devId > 0)
	{
		dsr.resize(1);
		dsr[0] = _cachedDsr[devId - 1];
		return dsr;
	}
	else if(devId == 0)
	{
		return _cachedDsr;
	}
	return dsr;
}

void
DataManager::hbCheck()
{
	u32 i;
	for(i=0;i<MAX_DEVS;i++)
	{
		if(_cachedDsr[i].cnt == 0)
		{
			_cachedDsr[i].devState = 0x0;
		}
		else
		{
			_cachedDsr[i].cnt -= 1;
		}
	}
}

// 重置对应设备的心跳超时计数
void
DataManager::hbReset(u8 devId)
{
	_cachedDsr[devId - 1].devId = devId;
	_cachedDsr[devId - 1].devState = IE_OK;
	_cachedDsr[devId - 1].cnt = HB_OMAX;
}

// 根据截止数据判断当前通道状态是否达到结束状态
s32
DataManager::checkVal(u32 endVal, u32 cntVal)
{
#define	GT		0x40000000
#define	LT		0x80000000
#define	CMASK	0xc0000000
#define	VMASK	0x3fffffff
	u32 endV = endVal & VMASK;
	if((endVal & CMASK) == GT)
	{
		if(cntVal >= endV*1000)
		{
			return IE_END_REACH;
		}
	}
	else if((endVal & CMASK) == LT)
	{
		if(cntVal <= endV*1000)
		{
			return IE_END_REACH;
		}
	}
	else
	{
		return	IE_ERR_PARAM;
	}
	return IE_END_UNREACH;
}

// 根据上报数据跟新通道信息
s32
DataManager::updateChn(u8 devId, ChnReport chnRep)
{
	u8 chnNo;
	s32	ret;
	ChnState *cs;
	bool bNotify;
	timespec ts;

	try
	{
		bNotify = false;
		chnNo = chnRep.chnNo;
		cs = &_cachedDsr[devId-1].csr[chnNo-1];
		// data update
		clock_gettime(0,&ts);
		cs->chnVol = chnRep.voltage;
		cs->chnCur = chnRep.current;
		cs->chnTemp = chnRep.temperature;
		// data calculate
		cs->chnWorkElapsed = gTaskManager.getTaskEla(devId,chnNo);
		cs->chnElapsed = gTaskManager.getStepEla(devId,chnNo);

		printf(">>>>>>>>>ms[%d]\n",cs->chnWorkElapsed);

		// data compare
		if(cs->endVoltage != 0 && !bNotify)
		{
			printf("===> vol\n");
			ret = checkVal(cs->endVoltage,cs->chnVol);
			if(ret == IE_END_REACH)
			{
				ret = gTaskManager.notifyEnd(devId,chnNo);
				if(ret == IE_OK) bNotify = true;
			}
		}
		if(cs->endCurrent != 0 && !bNotify)
		{
			printf("===> cur\n");
			ret = checkVal(cs->endCurrent,cs->chnCur);
			if(ret == IE_END_REACH)
			{
				ret = gTaskManager.notifyEnd(devId,chnNo);
				if(ret == IE_OK) bNotify = true;
			}
		}
		if(cs->endCapcity != 0 && !bNotify)
		{
			printf("===> cap\n");
			ret = checkVal(cs->endCapcity,cs->chnCap);
			if(ret == IE_END_REACH)
			{
				ret = gTaskManager.notifyEnd(devId,chnNo);
				if(ret == IE_OK) bNotify = true;
			}
		}
		if(cs->endEnergy != 0 && !bNotify)
		{
			printf("===> eng\n");
			ret = checkVal(cs->endEnergy,cs->chnEng);
			if(ret == IE_END_REACH)
			{
				ret = gTaskManager.notifyEnd(devId,chnNo);
				if(ret == IE_OK) bNotify = true;
			}
		}
		if(cs->endTime != 0 && !bNotify) // 其实无论充放电截止时间都作为大于条件存在
		{
			printf("===> time\n");
			ret = checkVal(cs->endTime,cs->chnElapsed);
			if(ret == IE_END_REACH)
			{
				printf("===> end reach !\n");
				ret = gTaskManager.notifyEnd(devId,chnNo); // 通知指定线程工步达到结束条件
				if(ret == IE_OK) bNotify = true;
			}
		}
	}
	catch(const Ice::Exception& ex)
	{
		printf("===============err=====>%s\n",ex.what());
	}
}

// 设置当前通道截止条件
s32
DataManager::setChnEnd(u8 devId, u8 chnNo, Step ss)
{
	ChnState *cs;
	cs = &_cachedDsr[devId-1].csr[chnNo-1];

	cs->endVoltage = ss.endVoltage;
	cs->endCurrent = ss.endVoltage;
	cs->endTime	= ss.endTime;
	cs->endCapcity = ss.endCapcity;
	cs->endEnergy = ss.endEnergy;
}

s32
DataManager::getDevState(u8 devId)
{
	return _cachedDsr[devId-1].devState;
}

void
DataManager::chnReset(u8 devId, u8 chnNo)
{
	ChnState cs;
	_cachedDsr[devId-1].csr[chnNo-1] = cs;
}

void
DataManager::chnSetName(u8 devId, u8 chnNo, string taskname)
{
	_cachedDsr[devId-1].csr[chnNo-1].taskName = taskname;// 改变设备号，通道号范围时需要注意不要越界
}

void
DataManager::chnSetSeq(u8 devId, u8 chnNo, s32 seq)
{
	_cachedDsr[devId-1].csr[chnNo-1].seq = seq;
}
